package com.itheima.sevrice.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.bean.Category;
import com.itheima.bean.Dish;
import com.itheima.bean.Setmeal;
import com.itheima.bean.SetmealDish;
import com.itheima.common.PageParam;
import com.itheima.dao.SetmealDao;
import com.itheima.dto.DishDto;
import com.itheima.dto.SetmealDto;
import com.itheima.exception.CustomException;
import com.itheima.sevrice.CategoryService;
import com.itheima.sevrice.DishService;
import com.itheima.sevrice.SetmealDishService;
import com.itheima.sevrice.SetmealService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@Service
@Transactional
public class SetmealServiceImpl implements SetmealService {

    @Autowired(required = false)
    private SetmealDao setmealDao;

    @Autowired
    //@Lazy
    private CategoryService categoryService;

    @Autowired
    private SetmealDishService setmealDishService;

    @Autowired
    private DishService dishService;

    /**
     * 分页查询
     *
     * @param pageParam
     * @return
     */
    @Override
    public IPage<SetmealDto> findPage(PageParam pageParam) {
        //构建分页条件对象
        IPage<Setmeal> page = new Page<>(pageParam.getPage(), pageParam.getPageSize());
        //构建条件对象
        LambdaQueryWrapper<Setmeal> lqw = new LambdaQueryWrapper<>();
        //追加条件
        lqw.like(pageParam.getName() != null, Setmeal::getName, pageParam.getName());
        //执行条件
        IPage<Setmeal> iPage = setmealDao.selectPage(page, lqw);

        //封装setmealdto 集合数据
        List<SetmealDto> dtoList = iPage.getRecords().stream().map(setmeal -> {
            //这里需要根据setmeal的id 去得到category 的名字
            Category category = categoryService.findBySetmealId(setmeal.getCategoryId());
            SetmealDto setmealDto = new SetmealDto();
            setmealDto.setCategoryName(category.getName());
            //拷贝其他的数据
            BeanUtils.copyProperties(setmeal, setmealDto);
            //TODO::这里套餐数据，还需要封装套餐拥有哪些菜品，这样在更新页面上就可以回显了
            List<SetmealDish> dishList = setmealDishService.findById(setmeal.getId());
            setmealDto.setSetmealDishes(dishList);

            return setmealDto;
        }).collect(Collectors.toList());

        //这里需要封装为SetmealDto  ，携带total总记录数和 当前页的集合数。
        IPage<SetmealDto> dtoIPage = new Page<>();
        dtoIPage.setTotal(iPage.getTotal());

        dtoIPage.setRecords(dtoList);

        return dtoIPage;
    }

    /**
     * 添加套餐 需要添加套餐数据 和 菜品数据
     *
     * @param setmealDto
     * @return
     */
    @Override
    @CacheEvict(value ="setmeal",allEntries = true)
    public int addSetmeal(SetmealDto setmealDto) {
        log.debug("***************新增套餐了************");
        int row1 = setmealDao.insert(setmealDto);

        //得到页面上所有的菜品集合
        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
        int row2 = 0;
        if (setmealDishes != null && setmealDishes.size() > 0) {
            for (SetmealDish setmealDish : setmealDishes) {
                //设置每一道菜 属于哪一个套餐
                setmealDish.setSetmealId(setmealDto.getId());
                // 添加套餐 菜品数据
                row2 += setmealDishService.add(setmealDish);
            }
            return row2 == setmealDishes.size() ? 1 : 0;
        }
        return row1;
    }

    /**
     * 删除套餐 1. 套餐的售卖状态是停售 2.还需要把套餐绑定的菜品数据删除掉
     *
     * @param ids
     * @return
     */
    @Override
    @CacheEvict(value ="setmeal",allEntries = true)
    public int deleteSetmeal(List<Long> ids) {
        log.debug("***************删除套餐了************");
        LambdaQueryWrapper<Setmeal> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Setmeal::getStatus, 1);
        lqw.in(Setmeal::getId, ids);
        Integer count = setmealDao.selectCount(lqw);
        if (count > 0) {
            throw new CustomException("套餐正在售卖中，不能删除~！");
        }
        //删除套餐绑定的菜品
        setmealDishService.delete(ids);
        return setmealDao.deleteBatchIds(ids);
    }

    /**
     * 修改状态
     *
     * @param status
     * @param ids
     * @return
     */
    @Override
    public int updateType(Integer status, List<Long> ids) {
        UpdateWrapper<Setmeal> wrapper = new UpdateWrapper<>();
        wrapper.set("status", status).in("id", ids);
        return setmealDao.update(null, wrapper);

    }

    /**
     * 根据套餐Id  封装套餐菜品 和setmeal 数据
     *
     * @param setmealId
     * @return
     */
    @Override
    public SetmealDto findById(Long setmealId) {
        LambdaQueryWrapper<Setmeal> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Setmeal::getId, setmealId);
        Setmeal setmeal = setmealDao.selectOne(lqw);
        //构建setmealDto
        SetmealDto dto = new SetmealDto();
        //调用setmealDish  查询绑定的套餐菜品
        List<SetmealDish> dishList = setmealDishService.findById(setmeal.getId());
        //把得到的套餐菜品 设置到
        dto.setSetmealDishes(dishList);

        //这里需要把setmeal 封装到setmealDto 中
        BeanUtils.copyProperties(setmeal, dto);
        return dto;

    }


    /**
     * 更新套餐
     *
     * @param setmealDto
     * @return
     */
    @Override
    public int updateSetmeal(SetmealDto setmealDto) {
        //根据套餐的id 更新套餐的数据
        int row1 = setmealDao.updateById(setmealDto);

        //需要更新套餐菜品的数据
        //1.先删除套餐的原来的套餐菜品， 再重新添加页面传过来的套餐菜品
        //1.根据套餐的id 删除套餐菜品
        setmealDishService.deleteById(setmealDto.getId());
        //重新获取页面上传过来的 套餐菜品数据
        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
        int row2 = 0;
        if (setmealDishes != null && setmealDishes.size() > 0) {
            //循环遍历套餐菜品 重新追加到套餐身上。
            for (SetmealDish setmealDish : setmealDishes) {
                //设置每一道菜 属于那一个套餐
                setmealDish.setSetmealId(setmealDto.getId());
                //调用套餐菜品 service
                row2 += setmealDishService.add(setmealDish);
            }
            return setmealDishes.size() == row2 ? 1 : 0;
        }
        return row1;
    }

    /**
     * 根据分类Id 和启售状态 查询套餐数据
     *
     * @param setmeal
     * @return
     */
    @Override
    @Cacheable(value = "setmeal",key = "#setmeal.getCategoryId()+'_'+#setmeal.getStatus()")
    public List<SetmealDto> findByCategoryId(Setmeal setmeal) {
        log.debug("************从mysql查询套餐数据了************");
        LambdaUpdateWrapper<Setmeal> lqw = new LambdaUpdateWrapper<>();
        lqw.eq(Setmeal::getStatus,setmeal.getStatus());
        lqw.eq(Setmeal::getCategoryId,setmeal.getCategoryId());
        List<Setmeal> setmealList = setmealDao.selectList(lqw);

        List<SetmealDto> setmealDtoList = setmealList.stream().map(s -> {
            SetmealDto dto = new SetmealDto();
            List<SetmealDish> dishList = setmealDishService.findById(s.getId());

            dto.setSetmealDishes(dishList);

            BeanUtils.copyProperties(s,dto);
            return dto;
        }).collect(Collectors.toList());
       // BeanUtils.copyProperties(setmealList,setmealDtoList);
        return setmealDtoList;
    }

    /**
     * 移动端查看套餐信息
     *
     * @param setmealId
     * @return
     */
    @Override
    public List<DishDto> findDish(Long setmealId) {
        //构建setmealDish 查询条件 ，根据套餐id 查询套餐菜品
        LambdaQueryWrapper<SetmealDish> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SetmealDish::getSetmealId,setmealId);
        List<SetmealDish> setmealDishList = setmealDishService.findById(setmealId);


        List<DishDto> dishDtoList = setmealDishList.stream().map(setmealDish -> {
            DishDto dishDto = new DishDto();
            Long dishId = setmealDish.getDishId();

            Dish dish = dishService.findById(dishId);

            BeanUtils.copyProperties(dish, dishDto);
            dishDto.setCopies(setmealDish.getCopies());
            return dishDto;
        }).collect(Collectors.toList());
        
        
       /* ArrayList<Long> dishIdList=new ArrayList<>();
        for (SetmealDish setmealDish : setmealDishList) {
            Long dishId = setmealDish.getDishId();
            dishIdList.add(dishId);
        }
        List<Dish> dishList = dishService.findById(dishIdList);

        DishDto dishDto = new DishDto();
        BeanUtils.*/
        return dishDtoList;
    }


}
